﻿#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="Layout.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2011 
//       Roland Rosenkranz (Glatzemann@email.de)
// </copyright>
// <license>
//   This file is part of starLiGHT.GUI.
//
//   It is released under the Microsoft Public License (Ms-PL).
//
//   You should have received a copy of the Microsoft Public License
//   along with starLiGHT.GUI. If not, see http://sle.codeplex.com/license.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.GUI are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev::                       $:  Revision of last commit *
// * $Author::                    $:  Author of last commit   *
// * $Date::                      $:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

namespace starLiGHT.GUI
{
#region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
#endregion

    public class Layout : SkinElement, IEquatable<Layout>
    {
        #region Member Variables
        private Skin skin;
        private Layout inherits;
        private Dictionary<string, State> states = new Dictionary<string, State>();
        private List<Property> properties = new List<Property>();
        private Color foreColor = Color.White;
        private Color backColor = Color.Black;
        private Vector2 minSize;
        private Vector2 maxSize;
        private Vector2 defaultSize;
        #endregion

        public Layout(Skin skin, string name)
            : base(name)
        {
            this.skin = skin;
            this.minSize = Vector2.Zero;
            this.maxSize = new Vector2(float.MaxValue);
        }

        public IEnumerable<State> States
        {
            get
            {
                foreach (State s in this.states.Values)
                {
                    yield return s;
                }
            }
        }

        public Skin Skin
        {
            get
            {
                return this.skin;
            }
        }

        public Color DefaultForeColor
        {
            get
            {
                return this.foreColor;
            }

            set
            {
                this.foreColor = value;
            }
        }

        public Color DefaultBackColor
        {
            get
            {
                return this.backColor;
            }

            set
            {
                this.backColor = value;
            }
        }

        public Vector2 MinimumSize
        {
            get
            {
                return this.minSize;
            }

            set
            {
                this.minSize = value;
                this.defaultSize = Vector2.Clamp(this.defaultSize, this.minSize, this.maxSize);
            }
        }

        public Vector2 MaximumSize
        {
            get
            {
                return this.maxSize;
            }

            set
            {
                this.maxSize = value;
                this.defaultSize = Vector2.Clamp(this.defaultSize, this.minSize, this.maxSize);
            }
        }

        public Vector2 DefaultSize
        {
            get
            {
                return this.defaultSize;
            }

            set
            {
                this.defaultSize = value;
                this.defaultSize = Vector2.Clamp(this.defaultSize, this.minSize, this.maxSize);
            }
        }

        public Layout Inherits
        {
            get
            {
                return this.inherits;
            }

            internal set
            {
                this.inherits = value;
            }
        }

        public void AddState(State state)
        {
            if (this.states.ContainsKey(state.Name))
            {
                State oldState = this.states[state.Name]; // new State(null, null); //this.states[this.states.IndexOf(state)];
                State superState = new State(state.Layout, state.Name);

                superState.BackColor = oldState.BackColor;
                if (state.BackColor.HasValue)
                {
                    superState.BackColor = state.BackColor;
                }

                superState.ForeColor = oldState.ForeColor;
                if (state.ForeColor.HasValue)
                {
                    superState.ForeColor = state.ForeColor;
                }

                foreach (Layer l in state.Layers)
                {
                    superState.AddLayer(l);
                }

                foreach (Layer l in oldState.Layers)
                {
                    superState.AddLayer(l);
                }

                this.states[state.Name] = superState;
            }
            else
            {
                this.states.Add(state.Name, state);
            }
        }

        public void AddProperty(Property prop)
        {
            this.properties.Add(prop);
        }

        public State GetState(string name)
        {
            string firstKey = String.Empty;

            foreach (State s in this.states.Values)
            {
                if (string.IsNullOrEmpty(firstKey))
                {
                    firstKey = s.Name;
                }

                if (s.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                {
                    return s;
                }
            }

            if (this.states != null &&
                this.states.Count > 0 &&
                !string.IsNullOrEmpty(firstKey))
            {
                return this.states[firstKey];
            }

            return null;
        }

        public Property GetProperty(string name)
        {
            foreach (Property p in this.properties)
            {
                if (p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                {
                    return p;
                }
            }

            return null;
        }

        public bool Equals(Layout other)
        {
            return this.Skin.Equals(other.Skin) && this.Name.Equals(other.Name, StringComparison.InvariantCultureIgnoreCase);
        }
    }
}
